Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / tests / backend / test_rnode_support.py

Displaying Raw • Download


tests/backend/test_rnode_support.py bce42bcdce0e7d2c6d78228e864a4cd1d974cc82 (bce42bcd) Text, 25.32 KB

T8b949e# SPDX-License-Identifier: 0BSD

Tff7b72import T7ee787pytest
Tff7b72from T7ee787hypothesis Tff7b72import Te6edf3givenTb4b4b4, Te6edf3settings
Tff7b72from T7ee787hypothesis Tff7b72import Te6edf3strategies Tff7b72as Te6edf3st

Tff7b72from T7ee787meshchatxT7ee787.T7ee787srcT7ee787.T7ee787backend Tff7b72import Te6edf3rnode_support


Tff7b72def Td2a8fftest_normalize_rnode_tcp_host_backfills_from_portTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
T8b949e"""RNS's Android RNodeInterface reads tcp_host as its own config key.

Configs written with only port = tcp://host:port (which is all the
desktop RNodeInterface needs) silently try to open the RNode as a serial
device on Android unless tcp_host is also present.
"""
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode TCP]]
type = RNodeInterface
interface_enabled = True
port = tcp://192.0.2.1:4242
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffnormalize_rnode_tcp_host_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Te6edf3text Tff7b72= Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6fftcp_host = 192.0.2.1:4242Ta5d6ff" Tff7b72in Te6edf3text


Tff7b72def Td2a8fftest_normalize_rnode_tcp_host_leaves_non_tcp_entries_aloneTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode Serial]]
type = RNodeInterface
interface_enabled = True
port = /dev/ttyUSB0
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffnormalize_rnode_tcp_host_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72False
Tff7b72assert Ta5d6ff"Ta5d6fftcp_hostTa5d6ff" Tff7b72not Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_normalize_rnode_tcp_host_is_idempotentTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode TCP]]
type = RNodeInterface
interface_enabled = True
port = tcp://192.0.2.1:4242
tcp_host = 192.0.2.1:4242
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffnormalize_rnode_tcp_host_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72False


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffparametrizeTb4b4b4(
Tb4b4b4(Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffexpectedTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4[
Tb4b4b4(Ta5d6ff"Ta5d6fftcp://192.0.2.1:4242Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff192.0.2.1:4242Ta5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6fftcp://mesh.exampleTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffmesh.exampleTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6fftcp://mesh.example:Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffmesh.exampleTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6fftcp://Ta5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6fftcp:///Ta5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ff/dev/ttyUSB0Ta5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)Tb4b4b4,
Tb4b4b4]Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_tcp_host_from_portTb4b4b4(Te6edf3portTb4b4b4, Te6edf3expectedTb4b4b4)Tb4b4b4:
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ff_tcp_host_from_portTb4b4b4(Te6edf3portTb4b4b4) Tff7b72== Te6edf3expected


Tff7b72def Td2a8fftest_normalize_rnode_tcp_host_handles_port_variantsTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode TCP]]
type = RNodeInterface
interface_enabled = True
port = TCP://mesh.example:4242
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffnormalize_rnode_tcp_host_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Ta5d6ff"Ta5d6fftcp_host = mesh.example:4242Ta5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffparametrizeTb4b4b4(
Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4,
Tb4b4b4[Ta5d6ff"Ta5d6fftcp://Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff tcp:// Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6fftcp:///Ta5d6ff"Tb4b4b4]Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_normalize_rnode_tcp_host_skips_empty_hostTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3portTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
Ta5d6fffTa5d6ff"""Ta5d6ff[interfaces]
Ta5d6ff[[RNode TCP]]
Ta5d6fftype = RNodeInterface
Ta5d6ffinterface_enabled = True
Ta5d6ffport = Tffd700{Te6edf3portTffd700}
Ta5d6ff"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffnormalize_rnode_tcp_host_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72False
Tff7b72assert Ta5d6ff"Ta5d6fftcp_hostTa5d6ff" Tff7b72not Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_normalize_rnode_tcp_host_updates_mismatched_tcp_hostTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode TCP]]
type = RNodeInterface
interface_enabled = True
port = tcp://192.0.2.1:4242
tcp_host = stale.example:1
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffnormalize_rnode_tcp_host_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Ta5d6ff"Ta5d6fftcp_host = 192.0.2.1:4242Ta5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_normalize_rnode_tcp_host_missing_file_returns_falseTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Tff7b72assert Tb4b4b4(
Te6edf3rnode_supportTff7b72.Td2a8ffnormalize_rnode_tcp_host_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffmissingTa5d6ff"Tb4b4b4)Tb4b4b4)
Tff7b72is Tff7b72False
Tb4b4b4)


Tff7b72def Td2a8fftest_normalize_rnode_tcp_host_invalid_config_returns_falseTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(Ta5d6ff"Ta5d6ffnot valid configobj syntax [[[Ta5d6ff"Tb4b4b4, Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffnormalize_rnode_tcp_host_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72False


Tff7b72def Td2a8fftest_guard_disables_rnode_when_usbserial4a_missingTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode Serial]]
type = RNodeInterface
interface_enabled = True
port = /dev/ttyUSB0
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_androidTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = falseTa5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_guard_disables_rnode_when_jnius_missingTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
T8b949e"""usbserial4a alone is not enough for serial/classic-Bluetooth ports.

RNS's Android RNodeInterface also needs jnius for those transports.
"""
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode Serial]]
type = RNodeInterface
interface_enabled = True
port = /dev/ttyUSB0
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_androidTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = falseTa5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_guard_keeps_rnode_when_usbserial4a_and_jnius_availableTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode Serial]]
type = RNodeInterface
interface_enabled = True
port = /dev/ttyUSB0
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_androidTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72False
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = TrueTa5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_guard_keeps_tcp_rnode_enabled_even_without_usbserial4a_or_jniusTb4b4b4(
Te6edf3tmp_pathTb4b4b4,
Te6edf3monkeypatchTb4b4b4,
Tb4b4b4)Tb4b4b4:
T8b949e"""RNode over TCP needs no native Android modules and must stay enabled."""
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode TCP]]
type = RNodeInterface
interface_enabled = True
port = tcp://192.0.2.1:4242
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_androidTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72False
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = TrueTa5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_guard_disables_ble_rnode_when_able_missingTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode BLE]]
type = RNodeInterface
interface_enabled = True
port = ble://aa:bb:cc:dd:ee:ff
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_able_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_androidTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = falseTa5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_guard_keeps_ble_rnode_when_able_availableTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode BLE]]
type = RNodeInterface
interface_enabled = True
port = ble://aa:bb:cc:dd:ee:ff
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_able_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_androidTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72False
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = TrueTa5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_guard_always_disables_rnode_multi_interface_on_androidTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
T8b949e"""RNS has no Android-specific RNodeMultiInterface; it always crashes there."""
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode Multi]]
type = RNodeMultiInterface
interface_enabled = True
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_able_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_androidTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = falseTa5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_guard_skips_rnode_multi_interface_off_androidTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode Multi]]
type = RNodeMultiInterface
interface_enabled = True
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_androidTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72False
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = TrueTa5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_guard_rnode_interfaces_on_desktop_disables_ble_without_bleakTb4b4b4(
Te6edf3tmp_pathTb4b4b4,
Te6edf3monkeypatchTb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode BLE]]
type = RNodeInterface
interface_enabled = True
port = ble://aa:bb:cc:dd:ee:ff
[[RNode TCP]]
type = RNodeInterface
interface_enabled = True
port = tcp://192.0.2.1:4242
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffdesktop_ble_stack_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffdesktop_serial_stack_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_desktopTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Te6edf3text Tff7b72= Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Tff7b72assert Te6edf3textTff7b72.Td2a8ffcountTb4b4b4(Ta5d6ff"Ta5d6ffinterface_enabled = falseTa5d6ff"Tb4b4b4) Tff7b72== T79c0ff1


Tff7b72def Td2a8fftest_guard_rnode_interfaces_on_desktop_skips_on_androidTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode BLE]]
type = RNodeInterface
interface_enabled = True
port = ble://aa:bb:cc:dd:ee:ff
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffdesktop_ble_stack_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_desktopTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72False
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = TrueTa5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_guard_skips_already_disabled_interfacesTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode Serial]]
type = RNodeInterface
interface_enabled = false
port = /dev/ttyUSB0
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_androidTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72False


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffparametrizeTb4b4b4(Ta5d6ff"Ta5d6ffenabled_keyTa5d6ff"Tb4b4b4, Tb4b4b4[Ta5d6ff"Ta5d6ffinterface_enabledTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffenabledTa5d6ff"Tb4b4b4]Tb4b4b4)
Tff7b72def Td2a8fftest_guard_honors_enabled_key_variantsTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3monkeypatchTb4b4b4, Te6edf3enabled_keyTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
Ta5d6fffTa5d6ff"""Ta5d6ff[interfaces]
Ta5d6ff[[RNode Serial]]
Ta5d6fftype = RNodeInterface
Tffd700{Te6edf3enabled_keyTffd700}Ta5d6ff = yes
Ta5d6ffport = /dev/ttyUSB0
Ta5d6ff"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_androidTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = falseTa5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_rnode_serial_supported_on_desktopTb4b4b4(Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffrnode_serial_supportedTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72True


Tff7b72def Td2a8fftest_rnode_serial_supported_on_android_requires_both_modulesTb4b4b4(Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffrnode_serial_supportedTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72False

Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffrnode_serial_supportedTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72False

Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffrnode_serial_supportedTb4b4b4(Tb4b4b4) Tff7b72is Tff7b72True


Tff7b72def Td2a8fftest_rnode_transport_supported_tcp_always_true_on_androidTb4b4b4(Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_able_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)

Tff7b72assert Tb4b4b4(
Te6edf3rnode_supportTff7b72.Td2a8ffrnode_transport_supportedTb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6fftcp://example.org:4242Ta5d6ff"Tb4b4b4}Tb4b4b4)
Tff7b72is Tff7b72True
Tb4b4b4)


Tff7b72def Td2a8fftest_rnode_transport_supported_tcp_always_true_on_desktop_without_pyserialTb4b4b4(
Te6edf3monkeypatchTb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffdesktop_serial_stack_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)

Tff7b72assert Tb4b4b4(
Te6edf3rnode_supportTff7b72.Td2a8ffrnode_transport_supportedTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6fftcp://example.org:4242Ta5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3is_androidTff7b72=Tff7b72FalseTb4b4b4,
Tb4b4b4)
Tff7b72is Tff7b72True
Tb4b4b4)


Tff7b72def Td2a8fftest_rnode_transport_supported_serial_false_on_desktop_without_pyserialTb4b4b4(
Te6edf3monkeypatchTb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffdesktop_serial_stack_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)

Tff7b72assert Tb4b4b4(
Te6edf3rnode_supportTff7b72.Td2a8ffrnode_transport_supportedTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ff/dev/ttyUSB0Ta5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3is_androidTff7b72=Tff7b72FalseTb4b4b4,
Tb4b4b4)
Tff7b72is Tff7b72False
Tb4b4b4)


Tff7b72def Td2a8fftest_rnode_transport_supported_bluetooth_classic_needs_usbserial_and_jniusTb4b4b4(
Te6edf3monkeypatchTb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)

Te6edf3iface Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffallow_bluetoothTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6fftrueTa5d6ff"Tb4b4b4}
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffrnode_transport_supportedTb4b4b4(Te6edf3ifaceTb4b4b4) Tff7b72is Tff7b72True

Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffrnode_transport_supportedTb4b4b4(Te6edf3ifaceTb4b4b4) Tff7b72is Tff7b72False


Tff7b72def Td2a8fftest_rnode_transport_supported_whitespace_port_with_bluetooth_classicTb4b4b4(
Te6edf3monkeypatchTb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)

Te6edf3iface Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ff Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffallow_bluetoothTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffyesTa5d6ff"Tb4b4b4}
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffrnode_transport_supportedTb4b4b4(Te6edf3ifaceTb4b4b4) Tff7b72is Tff7b72True


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffparametrizeTb4b4b4(
Tb4b4b4(Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffis_tcpTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffis_bleTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4[
Tb4b4b4(Ta5d6ff"Ta5d6fftcp://host:1Ta5d6ff"Tb4b4b4, Tff7b72TrueTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ffTCP://HOST:1Ta5d6ff"Tb4b4b4, Tff7b72TrueTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ff tcp://host Ta5d6ff"Tb4b4b4, Tff7b72TrueTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ffble://aa:bb:cc:dd:ee:ffTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ffBLE://AA:BBTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72TrueTb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ff/dev/ttyUSB0Ta5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Tff7b72NoneTb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ff Ta5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(T79c0ff123Tb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4(Ta5d6ff"Ta5d6ffserial://not-tcpTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4, Tff7b72FalseTb4b4b4)Tb4b4b4,
Tb4b4b4]Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_rnode_port_prefix_detectionTb4b4b4(Te6edf3portTb4b4b4, Te6edf3is_tcpTb4b4b4, Te6edf3is_bleTb4b4b4)Tb4b4b4:
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffrnode_port_is_tcpTb4b4b4(Te6edf3portTb4b4b4) Tff7b72is Te6edf3is_tcp
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffrnode_port_is_bleTb4b4b4(Te6edf3portTb4b4b4) Tff7b72is Te6edf3is_ble


Tf0883e@pytestTff7b72.Td2a8ffmarkTff7b72.Td2a8ffparametrizeTb4b4b4(
Tb4b4b4(Ta5d6ff"Ta5d6ffifaceTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffexpectedTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4[
Tb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6fftcp://host:1Ta5d6ff"Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6fftcpTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffble://aa:bbTa5d6ff"Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffbleTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffallow_bluetoothTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6fftrueTa5d6ff"Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffbluetooth_classicTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ff Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffallow_bluetoothTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffonTa5d6ff"Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffbluetooth_classicTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ff/dev/ttyUSB0Ta5d6ff"Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffserialTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4(Tb4b4b4{Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ff/dev/ttyUSB0Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffallow_bluetoothTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6fftrueTa5d6ff"Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffserialTa5d6ff"Tb4b4b4)Tb4b4b4,
Tb4b4b4]Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_rnode_iface_transport_classificationTb4b4b4(Te6edf3ifaceTb4b4b4, Te6edf3expectedTb4b4b4)Tb4b4b4:
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ff_rnode_iface_transportTb4b4b4(Te6edf3ifaceTb4b4b4) Tff7b72== Te6edf3expected


Tff7b72def Td2a8fftest_disable_rnode_interfaces_on_desktop_disables_serial_without_pyserialTb4b4b4(
Te6edf3tmp_pathTb4b4b4,
Te6edf3monkeypatchTb4b4b4,
Tb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode Serial]]
type = RNodeInterface
interface_enabled = True
port = /dev/ttyUSB0
[[RNode TCP]]
type = RNodeInterface
interface_enabled = True
port = tcp://192.0.2.1:4242
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffdesktop_serial_stack_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)

Tff7b72assert Tb4b4b4(
Te6edf3rnode_supportTff7b72.Td2a8ffdisable_rnode_interfaces_in_configTb4b4b4(
Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4,
Te6edf3is_androidTff7b72=Tff7b72FalseTb4b4b4,
Tb4b4b4)
Tff7b72is Tff7b72True
Tb4b4b4)
Te6edf3text Tff7b72= Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = falseTa5d6ff" Tff7b72in Te6edf3text
Tff7b72assert Te6edf3textTff7b72.Td2a8ffcountTb4b4b4(Ta5d6ff"Ta5d6ffinterface_enabled = falseTa5d6ff"Tb4b4b4) Tff7b72== T79c0ff1


Tff7b72def Td2a8fftest_guard_disables_rnode_with_invalid_txpowerTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[t9-srv]]
type = RNodeInterface
interface_enabled = True
port = /dev/ttyUSB0
frequency = 868000000
bandwidth = 125000
txpower = -9
spreadingfactor = 8
codingrate = 5
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_invalid_rnode_txpower_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Te6edf3text Tff7b72= Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = falseTa5d6ff" Tff7b72in Te6edf3textTff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)


Tff7b72def Td2a8fftest_guard_keeps_rnode_with_valid_txpowerTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[Radio]]
type = RNodeInterface
interface_enabled = True
txpower = 7
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72assert Tb4b4b4(
Te6edf3rnode_supportTff7b72.Td2a8ffguard_invalid_rnode_txpower_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72False
Tb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = TrueTa5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_guard_disables_rnode_multi_with_invalid_nested_txpowerTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode Multi]]
type = RNodeMultiInterface
interface_enabled = True

[[RNode Multi.r1]]
txpower = -9
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_invalid_rnode_txpower_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Tb4b4b4(
Ta5d6ff"Ta5d6ffinterface_enabled = falseTa5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Tb4b4b4)


Tff7b72def Td2a8fftest_guard_invalid_txpower_honors_enabled_keyTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[Radio]]
type = RNodeInterface
enabled = yes
txpower = -9
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_invalid_rnode_txpower_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Tb4b4b4(
Ta5d6ff"Ta5d6ffinterface_enabled = falseTa5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Tb4b4b4)


Tff7b72def Td2a8fftest_guard_invalid_txpower_skips_already_disabledTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[Radio]]
type = RNodeInterface
interface_enabled = false
txpower = -9
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72assert Tb4b4b4(
Te6edf3rnode_supportTff7b72.Td2a8ffguard_invalid_rnode_txpower_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72False
Tb4b4b4)


Tff7b72def Td2a8fftest_optional_module_available_uses_find_specTb4b4b4(Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(
Te6edf3rnode_supportTff7b72.Td2a8ffimportlibTff7b72.Td2a8ffutilTb4b4b4,
Ta5d6ff"Ta5d6fffind_specTa5d6ff"Tb4b4b4,
Tff7b72lambda Te6edf3nameTb4b4b4: Tffa657objectTb4b4b4(Tb4b4b4) Tff7b72if Te6edf3name Tff7b72== Ta5d6ff"Ta5d6ffpresentTa5d6ff" Tff7b72else Tff7b72NoneTb4b4b4,
Tb4b4b4)
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ff_optional_module_availableTb4b4b4(Ta5d6ff"Ta5d6ffpresentTa5d6ff"Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ff_optional_module_availableTb4b4b4(Ta5d6ff"Ta5d6ffmissingTa5d6ff"Tb4b4b4) Tff7b72is Tff7b72False


Tff7b72def Td2a8fftest_optional_module_available_handles_find_spec_errorsTb4b4b4(Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ff_boomTb4b4b4(Te6edf3_nameTb4b4b4)Tb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(Ta5d6ff"Ta5d6ffbroken meta pathTa5d6ff"Tb4b4b4)

Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTff7b72.Td2a8ffimportlibTff7b72.Td2a8ffutilTb4b4b4, Ta5d6ff"Ta5d6fffind_specTa5d6ff"Tb4b4b4, Te6edf3_boomTb4b4b4)
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ff_optional_module_availableTb4b4b4(Ta5d6ff"Ta5d6ffanythingTa5d6ff"Tb4b4b4) Tff7b72is Tff7b72False


Tf0883e@settingsTb4b4b4(Te6edf3max_examplesTff7b72=T79c0ff200Tb4b4b4, Te6edf3deadlineTff7b72=Tff7b72NoneTb4b4b4)
Tf0883e@givenTb4b4b4(
Te6edf3prefixTff7b72=Te6edf3stTff7b72.Td2a8ffsampled_fromTb4b4b4(Tb4b4b4[Ta5d6ff"Ta5d6fftcp://Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffTCP://Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff tcp://Ta5d6ff"Tb4b4b4]Tb4b4b4)Tb4b4b4,
Te6edf3hostTff7b72=Te6edf3stTff7b72.Td2a8fftextTb4b4b4(
Te6edf3alphabetTff7b72=Te6edf3stTff7b72.Td2a8ffcharactersTb4b4b4(Te6edf3blacklist_categoriesTff7b72=Tb4b4b4(Ta5d6ff"Ta5d6ffCsTa5d6ff"Tb4b4b4,Tb4b4b4)Tb4b4b4, Te6edf3blacklist_charactersTff7b72=Ta5d6ff"Ta5d6ff/Ta5d6ff"Tb4b4b4)Tb4b4b4,
Te6edf3min_sizeTff7b72=T79c0ff1Tb4b4b4,
Te6edf3max_sizeTff7b72=T79c0ff32Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_rnode_port_is_tcp_never_false_positive_on_tcp_prefixTb4b4b4(Te6edf3prefixTb4b4b4, Te6edf3hostTb4b4b4)Tb4b4b4:
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffrnode_port_is_tcpTb4b4b4(Ta5d6fffTa5d6ff"Tffd700{Te6edf3prefixTffd700}Tffd700{Te6edf3hostTffd700}Ta5d6ff"Tb4b4b4) Tff7b72is Tff7b72True


Tf0883e@settingsTb4b4b4(Te6edf3max_examplesTff7b72=T79c0ff200Tb4b4b4, Te6edf3deadlineTff7b72=Tff7b72NoneTb4b4b4)
Tf0883e@givenTb4b4b4(
Te6edf3noiseTff7b72=Te6edf3stTff7b72.Td2a8fftextTb4b4b4(Te6edf3min_sizeTff7b72=T79c0ff0Tb4b4b4, Te6edf3max_sizeTff7b72=T79c0ff16Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_rnode_port_is_tcp_rejects_non_tcp_prefixesTb4b4b4(Te6edf3noiseTb4b4b4)Tb4b4b4:
Te6edf3candidate Tff7b72= Te6edf3noiseTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3candidateTff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6fftcp://Ta5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72return
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffrnode_port_is_tcpTb4b4b4(Te6edf3candidateTb4b4b4) Tff7b72is Tff7b72False


Tff7b72def Td2a8fftest_normalize_rnode_tcp_host_backfills_rnode_ip_interfaceTb4b4b4(Te6edf3tmp_pathTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode IP]]
type = RNodeIPInterface
interface_enabled = True
port = tcp://192.0.2.5:4242
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffnormalize_rnode_tcp_host_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Ta5d6ff"Ta5d6fftcp_host = 192.0.2.5:4242Ta5d6ff" Tff7b72in Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)


Tff7b72def Td2a8fftest_rnode_transport_supported_ble_on_desktop_needs_bleakTb4b4b4(Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffdesktop_ble_stack_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffdesktop_serial_stack_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)

Tff7b72assert Tb4b4b4(
Te6edf3rnode_supportTff7b72.Td2a8ffrnode_transport_supportedTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffble://aa:bb:cc:dd:ee:ffTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3is_androidTff7b72=Tff7b72FalseTb4b4b4,
Tb4b4b4)
Tff7b72is Tff7b72False
Tb4b4b4)


Tff7b72def Td2a8fftest_rnode_transport_supported_ble_on_desktop_with_bleakTb4b4b4(Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffdesktop_ble_stack_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)

Tff7b72assert Tb4b4b4(
Te6edf3rnode_supportTff7b72.Td2a8ffrnode_transport_supportedTb4b4b4(
Tb4b4b4{Ta5d6ff"Ta5d6ffportTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffble://aa:bb:cc:dd:ee:ffTa5d6ff"Tb4b4b4}Tb4b4b4,
Te6edf3is_androidTff7b72=Tff7b72FalseTb4b4b4,
Tb4b4b4)
Tff7b72is Tff7b72True
Tb4b4b4)


Tff7b72def Td2a8fftest_disable_rnode_skips_sub_interface_siblingsTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode Multi]]
type = RNodeMultiInterface
interface_enabled = True

[[RNode Multi.r1]]
txpower = 7
frequency = 868000000
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_androidTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Te6edf3text Tff7b72= Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6ffinterface_enabled = falseTa5d6ff" Tff7b72in Te6edf3textTff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6fftxpower = 7Ta5d6ff" Tff7b72in Te6edf3text


Tff7b72def Td2a8fftest_startup_repair_sequence_applies_all_guardsTb4b4b4(Te6edf3tmp_pathTb4b4b4, Te6edf3monkeypatchTb4b4b4)Tb4b4b4:
Te6edf3config_path Tff7b72= Te6edf3tmp_path Tff7b72/ Ta5d6ff"Ta5d6ffconfigTa5d6ff"
Te6edf3config_pathTff7b72.Td2a8ffwrite_textTb4b4b4(
T8b949e"""[interfaces]
[[RNode TCP]]
type = RNodeInterface
interface_enabled = True
port = tcp://192.0.2.1:4242
txpower = -9

[[RNode Serial]]
type = RNodeInterface
interface_enabled = True
port = /dev/ttyUSB0
"""Tb4b4b4,
Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ff_is_chaquopy_androidTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72TrueTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_usbserial4a_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)
Te6edf3monkeypatchTff7b72.Td2a8ffsetattrTb4b4b4(Te6edf3rnode_supportTb4b4b4, Ta5d6ff"Ta5d6ffandroid_jnius_availableTa5d6ff"Tb4b4b4, Tff7b72lambdaTb4b4b4: Tff7b72FalseTb4b4b4)

Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffnormalize_rnode_tcp_host_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_rnode_interfaces_on_androidTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ffguard_invalid_rnode_txpower_in_configTb4b4b4(Tffa657strTb4b4b4(Te6edf3config_pathTb4b4b4)Tb4b4b4) Tff7b72is Tff7b72True

Te6edf3text Tff7b72= Te6edf3config_pathTff7b72.Td2a8ffread_textTb4b4b4(Te6edf3encodingTff7b72=Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Tff7b72assert Ta5d6ff"Ta5d6fftcp_host = 192.0.2.1:4242Ta5d6ff" Tff7b72in Te6edf3text
Tff7b72assert Te6edf3textTff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffcountTb4b4b4(Ta5d6ff"Ta5d6ffinterface_enabled = falseTa5d6ff"Tb4b4b4) Tff7b72== T79c0ff2


Tf0883e@settingsTb4b4b4(Te6edf3max_examplesTff7b72=T79c0ff100Tb4b4b4, Te6edf3deadlineTff7b72=Tff7b72NoneTb4b4b4)
Tf0883e@givenTb4b4b4(
Te6edf3hostTff7b72=Te6edf3stTff7b72.Td2a8fffrom_regexTb4b4b4(Ta5d6ffrTa5d6ff"Ta5d6ff[A-Za-z0-9][A-Za-z0-9.-]Ta5d6ff{Ta5d6ff0,31}Ta5d6ff"Tb4b4b4, Te6edf3fullmatchTff7b72=Tff7b72TrueTb4b4b4)Tb4b4b4,
Te6edf3portTff7b72=Te6edf3stTff7b72.Td2a8ffintegersTb4b4b4(Te6edf3min_valueTff7b72=T79c0ff1Tb4b4b4, Te6edf3max_valueTff7b72=T79c0ff65535Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8fftest_tcp_host_from_port_round_trips_host_portTb4b4b4(Te6edf3hostTb4b4b4, Te6edf3portTb4b4b4)Tb4b4b4:
Te6edf3value Tff7b72= Ta5d6fffTa5d6ff"Ta5d6fftcp://Tffd700{Te6edf3hostTffd700}Ta5d6ff:Tffd700{Te6edf3portTffd700}Ta5d6ff"
Tff7b72assert Te6edf3rnode_supportTff7b72.Td2a8ff_tcp_host_from_portTb4b4b4(Te6edf3valueTb4b4b4) Tff7b72== Ta5d6fffTa5d6ff"Tffd700{Te6edf3hostTffd700}Ta5d6ff:Tffd700{Te6edf3portTffd700}Ta5d6ff"


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────